#ifndef CONF_SERVER_H
#define CONF_SERVER_H

#include <muduo/base/Atomic.h>
#include <muduo/base/Logging.h>
#include <muduo/base/Thread.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/TcpServer.h>
#include <muduo/net/InetAddress.h>

#include <boost/bind.hpp>

#include <string.h>

using namespace muduo;
using namespace muduo::net;

namespace sdfs
{

namespace storage
{
const string REQ_UPDATE="UPDATE\r\n";
const string REQ_SHUTDOWN="SHUTDOWN\r\n";
const string REQ_RESTART="RESTART\r\n";

class ConfigServer
{
public:
	ConfigServer(EventLoop* loop, const InetAddress& addr)
		:server_(loop, addr, "ConfigServer"),
		 startTime_(Timestamp::now())
	{
		server_.setConnectionCallback(
			boost::bind(&ConfigServer::onConnection, this, _1));
		server_.setMessageCallback(
			boost::bind(&ConfigServer::onMessage, this, _1, _2, _3));
	}

	void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp)
	{
		LOG_DEBUG << conn->name();
		size_t len = buf->readableBytes();
		if(len > 0)
		{
			string reqkey = buf->retrieveAllAsString();
			LOG_DEBUG << reqkey;
			if(reqkey.compare(REQ_UPDATE) == 0 )
			{
				server_.getLoop()->runInLoop(boost::bind(&ConfigServer::update, this));
			}
			else if(reqkey.compare(REQ_SHUTDOWN) == 0)
			{
				server_.getLoop()->runInLoop(boost::bind(&ConfigServer::shutdown, this));
				
			}
			else if(reqkey.compare(REQ_RESTART) == 0)
			{
				server_.getLoop()->runInLoop(boost::bind(&ConfigServer::restart, this));
			}
		}
	}

	void onConnection(const TcpConnectionPtr& conn)
	{
		LOG_DEBUG << conn->peerAddress().toIpPort() <<
			" -> " << conn->localAddress().toIpPort() <<
			" is " << (conn->connected() ? "UP" : "DOWN");
	}

	void update();

	void shutdown();

	void restart();

	void start()
	{
		LOG_DEBUG << "starting config server";
		server_.start();
	}

	/* data */
private:
	TcpServer server_;
	Timestamp startTime_;
	int threadNum_;
};

}
}
#endif
